package top.codef.money;

import java.text.DecimalFormat;
import java.util.Currency;
import java.util.Objects;

import javax.money.CurrencyUnit;
import javax.money.MonetaryAmount;
import javax.money.format.AmountFormatContext;

import org.javamoney.moneta.format.CurrencyStyle;

import top.codef.money.interfaces.MoneyPrinter;

public class MercuryMoneyPrinter implements MoneyPrinter {

	private final String pattern;

	private final AmountFormatContext amountFormatContext;

	private static final String CURRENCY_SIGN = "\u00A4";

	public MercuryMoneyPrinter(String pattern, AmountFormatContext amountFormatContext) {
		if (pattern == null)
			pattern = ((DecimalFormat) DecimalFormat.getCurrencyInstance(amountFormatContext.getLocale())).toPattern();
		this.pattern = pattern;
		this.amountFormatContext = amountFormatContext;
	}

	@Override
	public String print(MonetaryAmount amount) {
		int index = pattern.indexOf(CURRENCY_SIGN);
		if (index != -1) {
			String numPattern = pattern.replace(CURRENCY_SIGN, currencyPrint(amount.getCurrency()));
			String result = new DecimalFormat(numPattern).format(amount.getNumber());
			return result;
		} else
			return new DecimalFormat(pattern).format(amount.getNumber());
	}

	private String currencyPrint(CurrencyUnit currencyUnit) {
		CurrencyStyle currencyStyle = amountFormatContext.get(CurrencyStyle.class);
		currencyStyle = currencyStyle == null ? CurrencyStyle.CODE : currencyStyle;
		switch (currencyStyle) {
		case CODE:
			return currencyUnit.getCurrencyCode();
		case NAME:
			return getCurrencyName(currencyUnit);
		case SYMBOL:
			return getCurrencySymbol(currencyUnit);
		default:
		}
		throw new UnsupportedOperationException("不支持的操作");
	}

	private String getCurrencyName(CurrencyUnit currency) {
		Currency jdkCurrency = getCurrency(currency.getCurrencyCode());
		if (Objects.nonNull(jdkCurrency)) {
			return jdkCurrency.getDisplayName(amountFormatContext.getLocale());
		}
		return currency.getCurrencyCode();
	}

	private String getCurrencySymbol(CurrencyUnit currency) {
		Currency jdkCurrency = getCurrency(currency.getCurrencyCode());
		if (Objects.nonNull(jdkCurrency)) {
			return jdkCurrency.getSymbol(amountFormatContext.getLocale());
		}
		return currency.getCurrencyCode();
	}

	private Currency getCurrency(String currencyCode) {
		try {
			return Currency.getInstance(currencyCode);
		} catch (Exception e) {
			return null;
		}
	}
}
